package Model;

public class AIPlayer implements Player{
    private final String name;
    private Board board;

    public AIPlayer(String name){
        this.name = name;
    }

    //读取board棋盘，需要其定义的 判断胜负的逻辑
    public void setBoard(Board board){
        this.board = board;
    }

    @Override
    public String getName() {
        return name;
    }

    /**
     * 极小极大算法实现AI决策
     * @param state 当前棋盘状态数组
     * @return 最佳落子的分数评估
     */
    //AI算法相关以下3个
    public int minimax(String[] state) {
        int bestValue = board.getWin();
        int index = 0;

        for(int i = 0; i < 9; i++)
        {
            if(state[i].isEmpty())
            {
                state[i] = "O";
                int value = max(state);//按最坏的情况搜索，也就是对手总是极大化自己的价值
                if(value < bestValue)//保持不败
                {
                    bestValue = value;
                    index = i;
                }
                state[i] = "";
            }
        }
        return index;
    }

    public int min(String[] state) {

        int evalValue = board.Judge();
        if(evalValue == board.getWin())//由于状态空间较小，可直接搜索到终局
        {
            return board.getWin();
        }
        else if(evalValue == board.getLose())
        {
            return board.getLose();
        }
        else if(evalValue == board.getDraw())
        {
            return board.getDraw();
        }
        else
        {
            int bestValue = board.getWin();
            for(int i = 0; i < 9; i++)
            {
                if(state[i].isEmpty())
                {
                    state[i] = "O";
                    bestValue = Math.min(bestValue, max(state));
                    state[i] = "";
                }
            }
            return bestValue;
        }
    }

    public int max(String[] state) {
        int evalValue = board.Judge();
        if(evalValue == board.getWin())//由于井字棋搜索空间较小，可以直接搜索到终局
        {
            return board.getWin();
        }
        else if(evalValue == board.getLose())
        {
            return board.getLose();
        }
        else if(evalValue == board.getDraw())
        {
            return board.getDraw();
        }
        else
        {
            int bestValue = board.getLose();
            for(int i = 0; i < 9; i++)
            {
                if(state[i].isEmpty()) {
                    state[i] = "X";
                    bestValue = Math.max(bestValue, min(state));
                    state[i] = "";
                }
            }
            return bestValue;
        }
    }
}
